#include "tq.h"
#include <errno.h>  // 添加这行
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image.h"
#include "stb_image_write.h"

// 用于CURL写回调的结构体
struct MemoryStruct {
    char* memory;
    size_t size;
};

// CURL写回调函数
static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    size_t realsize = size * nmemb;
    struct MemoryStruct* mem = (struct MemoryStruct*)userp;

    char* ptr = realloc(mem->memory, mem->size + realsize + 1);
    if (!ptr) {
        printf("Not enough memory (realloc returned NULL)\n");
        return 0;
    }

    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;

    return realsize;
}

// 初始化tq结构体
tq* tq_init(const char* city_id) {
    tq* self = (tq*)malloc(sizeof(tq));
    if (!self) return NULL;

    self->city_id = city_id ? strdup(city_id) : strdup("AFYaW");
    if (!self->city_id) {
        free(self);
        return NULL;
    }

    return self;
}

// 释放tq结构体
void tq_free(tq* self) {
    if (self) {
        free(self->city_id);
        free(self);
    }
}

// 获取位置信息
cJSON* tq_dw(tq* self) {
    CURL* curl = curl_easy_init();
    if (!curl) return NULL;

    struct MemoryStruct chunk;
    chunk.memory = malloc(1);
    chunk.size = 0;

    curl_easy_setopt(curl, CURLOPT_URL, "http://www.nmc.cn/rest/position?");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        free(chunk.memory);
        curl_easy_cleanup(curl);
        return NULL;
    }

    curl_easy_cleanup(curl);

    cJSON* json = cJSON_Parse(chunk.memory);
    free(chunk.memory);

    return json;
}

// 获取天气信息
cJSON* tq_dwtq(tq* self) {
    cJSON* resf = tq_dw(self);
    if (!resf) return NULL;

    cJSON* code = cJSON_GetObjectItemCaseSensitive(resf, "code");
    if (code && cJSON_IsString(code)) {
        free(self->city_id);
        self->city_id = strdup(code->valuestring);
    }

    cJSON_Delete(resf);
    return tq_v1(self);
}

// 获取天气信息v1
cJSON* tq_v1(tq* self) {
    char url[256];
    snprintf(url, sizeof(url), "http://www.nmc.cn/rest/weather?stationid=%s", self->city_id);

    CURL* curl = curl_easy_init();
    if (!curl) return NULL;

    struct MemoryStruct chunk;
    chunk.memory = malloc(1);
    chunk.size = 0;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        free(chunk.memory);
        curl_easy_cleanup(curl);
        return NULL;
    }

    curl_easy_cleanup(curl);
    printf("URL: %s\n", url);

    cJSON* json = cJSON_Parse(chunk.memory);
    free(chunk.memory);

    return json;
}

// 简单的双线性插值缩放函数
static void resize_image(const unsigned char* input, int in_w, int in_h, 
                        unsigned char* output, int out_w, int out_h, int channels) {
    float x_ratio = (float)in_w / (float)out_w;
    float y_ratio = (float)in_h / (float)out_h;

    for (int y = 0; y < out_h; y++) {
        for (int x = 0; x < out_w; x++) {
            float px = x * x_ratio;
            float py = y * y_ratio;
            
            int x_low = (int)px;
            int y_low = (int)py;
            int x_high = x_low + 1;
            int y_high = y_low + 1;
            
            if (x_high >= in_w) x_high = x_low;
            if (y_high >= in_h) y_high = y_low;
            
            float x_weight = px - x_low;
            float y_weight = py - y_low;
            
            for (int c = 0; c < channels; c++) {
                float val = 
                    input[(y_low * in_w + x_low) * channels + c] * (1 - x_weight) * (1 - y_weight) +
                    input[(y_low * in_w + x_high) * channels + c] * x_weight * (1 - y_weight) +
                    input[(y_high * in_w + x_low) * channels + c] * (1 - x_weight) * y_weight +
                    input[(y_high * in_w + x_high) * channels + c] * x_weight * y_weight;
                
                output[(y * out_w + x) * channels + c] = (unsigned char)val;
            }
        }
    }
}

// 下载并缩放天气图标
int tq_down_png(tq* self, const char* name) {
    // 验证文件名
    if (!name || strstr(name, "..") || strchr(name, '/')) {
        fprintf(stderr, "无效的文件名\n");
        return 0;
    }

    // 检查文件是否已存在
    char final_filename[512];
    snprintf(final_filename, sizeof(final_filename), "weather_icons/%s", name);
    FILE* test = fopen(final_filename, "r");
    if (test) {
        fclose(test);
        printf("文件已存在: %s\n", final_filename);
        return 1;
    }

    char url[256];
    snprintf(url, sizeof(url), "http://image.nmc.cn/assets/img/w/40x40/4/%s", name);

    // 创建目录（带错误检查）
    if (mkdir("weather_icons", 0755) != 0 && errno != EEXIST) {
        perror("无法创建目录");
        return 0;
    }

    char temp_filename[512];
    snprintf(temp_filename, sizeof(temp_filename), "weather_icons/temp_%s", name);

    // 下载图片（带更详细的错误处理）
    CURL* curl = curl_easy_init();
    if (!curl) {
        fprintf(stderr, "无法初始化CURL\n");
        return 0;
    }

    FILE* fp = fopen(temp_filename, "wb");
    if (!fp) {
        perror("无法创建临时文件");
        curl_easy_cleanup(curl);
        return 0;
    }

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);

    CURLcode res = curl_easy_perform(curl);
    fclose(fp);

    if (res != CURLE_OK) {
        fprintf(stderr, "下载失败: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
        remove(temp_filename);
        return 0;
    }
    curl_easy_cleanup(curl);

    // 加载并处理图像（带更多错误检查）
    int width, height, channels;
    unsigned char* img_data = stbi_load(temp_filename, &width, &height, &channels, 0);
    if (!img_data) {
        fprintf(stderr, "无法加载图像: %s (%s)\n", temp_filename, stbi_failure_reason());
        remove(temp_filename);
        return 0;
    }

    if (channels < 3 || channels > 4) {
        fprintf(stderr, "不支持的图像格式: %d 通道\n", channels);
        stbi_image_free(img_data);
        remove(temp_filename);
        return 0;
    }

    // 缩放图像
    const int new_width = 40;
    const int new_height = 40;
    unsigned char* resized_img = (unsigned char*)malloc(new_width * new_height * channels);
    if (!resized_img) {
        fprintf(stderr, "内存不足\n");
        stbi_image_free(img_data);
        remove(temp_filename);
        return 0;
    }

    resize_image(img_data, width, height, resized_img, new_width, new_height, channels);
    stbi_image_free(img_data);

    // 保存结果
    if (!stbi_write_png(final_filename, new_width, new_height, channels, resized_img, new_width * channels)) {
        fprintf(stderr, "保存图像失败\n");
        free(resized_img);
        remove(temp_filename);
        return 0;
    }

    free(resized_img);
    remove(temp_filename);
    printf("成功下载并处理: %s\n", final_filename);
    return 1;
}
